home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-09-17 | 16.8 KB | 583 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: PRList.cpp
- // Release Version: $ ODF 2 $
- //
- // Copyright: (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #include "FWFound.hpp"
-
- #ifndef PRLIST_H
- #include "PRList.h"
- #endif
-
- #ifndef FWDEBUG_H
- #include "FWDebug.h"
- #endif
-
- #ifdef FW_BUILD_MAC
- #include <Errors.h>
- #endif
-
- //========================================================================================
- // FW_CPrivLink
- //========================================================================================
-
- #ifdef FW_BUILD_MAC
- #pragma segment fwcollec
- #endif
-
- //========================================================================================
- // FW_CPrivLink
- //========================================================================================
- // Many of the simple link methods are inlines; see PRList.h for implementations.
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLink::FW_CPrivLink
- //----------------------------------------------------------------------------------------
- // Constructor for FW_CPrivLink
-
- FW_CPrivLink::FW_CPrivLink() :
- fNext(NULL),
- fPrevious(NULL)
- {
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLink::FW_CPrivLink
- //----------------------------------------------------------------------------------------
- // Constructor for FW_CPrivLink
-
- FW_CPrivLink::FW_CPrivLink(FW_CPrivLink* next, FW_CPrivLink* previous) :
- fNext(next),
- fPrevious(previous)
- {
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLink::FW_CPrivLink
- //----------------------------------------------------------------------------------------
- // Copy constructor for FW_CPrivLink
-
- FW_CPrivLink::FW_CPrivLink(const FW_CPrivLink &link) :
- fNext(link.fNext),
- fPrevious(link.fPrevious)
- {
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLink::FW_CPrivLink
- //----------------------------------------------------------------------------------------
- // Destructor for FW_CPrivLink
-
- FW_CPrivLink::~FW_CPrivLink()
- {
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLink::Remove
- //----------------------------------------------------------------------------------------
- // Remove a link from its list (if any). DO NOT call this directly if there are
- // any iterators active on the list; use FW_CPrivLinkedList::Remove instead.
-
- void FW_CPrivLink::Remove( )
- {
- if( fPrevious )
- fPrevious->SetNext(fNext);
- if( fNext )
- fNext->SetPrevious(fPrevious);
- fNext = NULL;
- fPrevious = NULL;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLink::AddBefore
- //----------------------------------------------------------------------------------------
- // Add a link to a list before another link. It must not already be on any list.
- // DO NOT call this directly if there are any iterators active on the list;
- // use FW_CPrivLinkedList::Remove instead.
-
- void FW_CPrivLink::AddBefore( FW_CPrivLink *link )
- {
- FW_ASSERT(link!=NULL);
- FW_ASSERT(fNext==NULL);
- FW_ASSERT(fPrevious==NULL);
- fNext = link;
- fPrevious = link->GetPrevious();
- fPrevious->SetNext(this);
- fNext->SetPrevious(this);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLink::AddAfter
- //
- // Add a link to a list after another link. It must not already be on any list.
- // DO NOT call this directly if there are any iterators active on the list;
- // use FW_CPrivLinkedList::Remove instead.
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivLink::AddAfter( FW_CPrivLink *link )
- {
- FW_ASSERT(link!=NULL);
- FW_ASSERT(fNext==NULL);
- FW_ASSERT(fPrevious==NULL);
- fPrevious = link;
- fNext = link->GetNext();
- fPrevious->SetNext(this);
- fNext->SetPrevious(this);
- }
-
- //========================================================================================
- // Class FW_CPrivLinkedList
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedList::FW_CPrivLinkedList
- //----------------------------------------------------------------------------------------
- // Constructor for FW_CPrivLinkedList
-
- FW_CPrivLinkedList::FW_CPrivLinkedList()
- :fSentinel(&fSentinel,&fSentinel),
- fSeed(0),
- fCount(0)
- {
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedList::~FW_CPrivLinkedList
- //----------------------------------------------------------------------------------------
- // Destructor for FW_CPrivLinkedList
-
- FW_CPrivLinkedList::~FW_CPrivLinkedList()
- {
- // The list does NOT delete all its links!
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedList::IsEmpty
- //----------------------------------------------------------------------------------------
-
- FW_Boolean FW_CPrivLinkedList::IsEmpty() const
- {
- return this->IsSentinel( fSentinel.GetNext() );
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedList::Count
- //----------------------------------------------------------------------------------------
-
- unsigned long FW_CPrivLinkedList::Count() const
- {
- return fCount;
- /*
- FW_CPrivLink* l = fSentinel.GetNext();
- unsigned long count = 0;
- while (this->NotSentinel(l))
- {
- count++;
- l = l->GetNext();
- }
- return count;
- */
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedList::Includes
- //----------------------------------------------------------------------------------------
- // Does the list include a particular link?
-
- FW_Boolean FW_CPrivLinkedList::Includes( const FW_CPrivLink *link ) const
- {
- FW_CPrivLink* l = fSentinel.GetNext();
- while (this->NotSentinel(l))
- {
- if( l == link )
- return TRUE;
- else
- l = l->GetNext();
- }
- return FALSE;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedList::DeleteAllLinks
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivLinkedList::DeleteAllLinks()
- {
-
- FW_CPrivLink* l = fSentinel.GetNext();
- FW_CPrivLink* n = l;
- while (this->NotSentinel(n))
- {
- n = l->GetNext();
- delete l;
- l = n;
- }
- fSentinel.SetNext(&fSentinel);
- fSentinel.SetPrevious(&fSentinel);
- fSeed++;
- fCount = 0;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedList::RemoveAll
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivLinkedList::RemoveAll()
- {
- FW_CPrivLink* l = fSentinel.GetNext();
- FW_CPrivLink* n = l;
- while (this->NotSentinel(l))
- {
- n = l->GetNext();
- l->SetNext(NULL);
- l->SetPrevious(NULL);
- l = n;
- }
- fSentinel.SetNext(&fSentinel);
- fSentinel.SetPrevious(&fSentinel);
- fSeed++;
- fCount = 0;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedList::Remove
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivLinkedList::Remove(FW_CPrivLink* aLink)
- {
- fSeed++;
- fCount--;
- aLink->Remove();
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedList::RemoveFirst
- //----------------------------------------------------------------------------------------
-
- FW_CPrivLink* FW_CPrivLinkedList::RemoveFirst()
- {
- FW_CPrivLink* old = fSentinel.GetNext();
- if (this->NotSentinel(old))
- {
- fSeed++;
- fCount--;
- old->Remove();
- return old;
- }
- else
- {
- return NULL;
- }
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedList::RemoveLast
- //----------------------------------------------------------------------------------------
-
- FW_CPrivLink* FW_CPrivLinkedList::RemoveLast()
- {
- FW_CPrivLink* old = fSentinel.GetPrevious();
- if (this->NotSentinel(old))
- {
- fSeed++;
- fCount--;
- old->Remove();
- return old;
- }
- else
- {
- return NULL;
- }
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedList::AddFirst
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivLinkedList::AddFirst(FW_CPrivLink* link)
- {
- link->AddAfter(this->GetSentinel());
- fSeed++;
- fCount++;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedList::AddLast( FW_CPrivLink )
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivLinkedList::AddLast(FW_CPrivLink* link)
- {
- link->AddBefore(this->GetSentinel());
- fSeed++;
- fCount++;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedList::AddLast( FW_CPrivLinkedList )
- //----------------------------------------------------------------------------------------
- // Append contents of another list to my end. (Other list becomes empty.)
-
- void FW_CPrivLinkedList::AddLast(FW_CPrivLinkedList &list)
- {
- if( !list.IsEmpty() ) {
- FW_CPrivLink *myLast = fSentinel.GetPrevious();
- FW_CPrivLink *itsFirst = list.First();
- myLast->SetNext(itsFirst);
- itsFirst->SetPrevious(myLast);
-
- FW_CPrivLink *itsLast = list.Last();
- itsLast->SetNext(this->GetSentinel());
- fSentinel.SetPrevious(itsLast);
-
- list.fSentinel.SetNext(this->GetSentinel());
- list.fSentinel.SetPrevious(this->GetSentinel());
-
- fSeed++;
- fCount++;
- list.fSeed++;
- }
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedList::AddLastUnique( FW_CPrivLinkedList )
- //----------------------------------------------------------------------------------------
- // Append contents of another list (w/o duplication) to my end.
-
- void FW_CPrivLinkedList::AddLastUnique(FW_CPrivLinkedList &list)
- {
- for( FW_CPrivLink *link = fSentinel.GetNext(); this->NotSentinel(link); link=link->GetNext() )
- if( list.Includes(link) )
- list.Remove(link);
- this->AddLast(list);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedList::AddBefore
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivLinkedList::AddBefore(FW_CPrivLink* existing, FW_CPrivLink* link)
- {
- link->AddBefore(existing);
- fSeed++;
- fCount++;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedList::AddAfter
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivLinkedList::AddAfter(FW_CPrivLink* existing, FW_CPrivLink* link)
- {
- link->AddAfter(existing);
- fSeed++;
- fCount++;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedList::After
- //----------------------------------------------------------------------------------------
-
- FW_CPrivLink* FW_CPrivLinkedList::After(const FW_CPrivLink* link) const
- {
- FW_CPrivLink *next = link->GetNext();
- return (this->IsSentinel(next)) ? NULL : next;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedList::Before
- //----------------------------------------------------------------------------------------
-
- FW_CPrivLink* FW_CPrivLinkedList::Before(const FW_CPrivLink* link) const
- {
- FW_CPrivLink *prev = link->GetPrevious();
- return this->IsSentinel(prev) ? NULL : prev;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedList::First
- //----------------------------------------------------------------------------------------
-
- FW_CPrivLink* FW_CPrivLinkedList::First() const
- {
- return this->NotSentinel(fSentinel.GetNext()) ? fSentinel.GetNext() : (FW_CPrivLink*) NULL;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedList::Last
- //----------------------------------------------------------------------------------------
-
- FW_CPrivLink* FW_CPrivLinkedList::Last() const
- {
- return this->NotSentinel(fSentinel.GetPrevious()) ? fSentinel.GetPrevious() : (FW_CPrivLink*) NULL;
- }
-
- //========================================================================================
- // Class FW_CPrivLinkedListIterator
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedListIterator::FW_CPrivLinkedListIterator
- //----------------------------------------------------------------------------------------
- // Constructor for FW_CPrivLinkedListIterator
-
- FW_CPrivLinkedListIterator::FW_CPrivLinkedListIterator(FW_CPrivLinkedList* list) :
- fList(list),
- fCurrent(NULL),
- fNext(NULL),
- fPrevious(NULL),
- fSentinel(list ? &list->fSentinel : NULL),
- fSeed(list ? fList->fSeed : 0)
- {
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedListIterator::~FW_CPrivLinkedListIterator
- //----------------------------------------------------------------------------------------
- // Destructor for FW_CPrivLinkedListIterator
-
- FW_CPrivLinkedListIterator::~FW_CPrivLinkedListIterator()
- {
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedListIterator::First
- //----------------------------------------------------------------------------------------
-
- FW_CPrivLink* FW_CPrivLinkedListIterator::First()
- {
- if (fList == NULL)
- return NULL;
-
- FW_ASSERT(fSeed == fList->fSeed);
-
- fCurrent = fList->First();
- if (fCurrent == fSentinel)
- fCurrent = NULL;
- return fCurrent;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedListIterator::Next
- //----------------------------------------------------------------------------------------
-
- FW_CPrivLink* FW_CPrivLinkedListIterator::Next()
- {
- if (fList == NULL)
- return NULL;
-
- FW_ASSERT(fSeed == fList->fSeed);
-
- if (fCurrent == NULL)
- {
- if ((fNext == NULL) && (fPrevious == NULL)) // Just starting out
- {
- return this->First();
- }
- else // Just deleted
- {
- fCurrent = fNext;
- fPrevious = NULL;
- fNext = NULL;
- }
- }
- else
- fCurrent = fCurrent->GetNext();
-
- if (fCurrent == fSentinel)
- fCurrent = NULL;
- return fCurrent;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedListIterator::Last
- //----------------------------------------------------------------------------------------
-
- FW_CPrivLink* FW_CPrivLinkedListIterator::Last()
- {
- if (fList == NULL)
- return NULL;
-
- FW_ASSERT(fSeed == fList->fSeed);
-
- fCurrent = fList->Last();
- if (fCurrent == fSentinel)
- fCurrent = NULL;
- return fCurrent;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedListIterator::Previous
- //----------------------------------------------------------------------------------------
-
- FW_CPrivLink* FW_CPrivLinkedListIterator::Previous()
- {
- if (fList == NULL)
- return NULL;
-
- FW_ASSERT(fSeed == fList->fSeed);
-
- if (fCurrent == NULL)
- {
- if ((fNext == NULL) && (fPrevious == NULL)) // Just starting out
- {
- return this->Last();
- }
- else // Just deleted
- {
- fCurrent = fPrevious;
- fPrevious = NULL;
- fNext = NULL;
- }
- }
- else
- fCurrent = fCurrent->GetPrevious();
-
- if (fCurrent == fSentinel)
- fCurrent = NULL;
- return fCurrent;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedListIterator::Current
- //----------------------------------------------------------------------------------------
-
- FW_CPrivLink* FW_CPrivLinkedListIterator::Current()
- {
- return fCurrent;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedListIterator::IsNotComplete
- //----------------------------------------------------------------------------------------
-
- FW_Boolean FW_CPrivLinkedListIterator::IsNotComplete()
- {
- return (fCurrent != NULL);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivLinkedListIterator::RemoveCurrent
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivLinkedListIterator::RemoveCurrent()
- {
- if (fList == NULL)
- return;
-
- FW_ASSERT(fSeed == fList->fSeed);
-
- if (fCurrent != NULL)
- {
- fNext = fCurrent->GetNext();
- fPrevious = fCurrent->GetPrevious();
-
- fList->Remove(fCurrent);
- fCurrent = NULL;
- fSeed = fList->fSeed;
- }
- }
-